<?
	/*
	 * DLOG simple logging class
	 * $Header: d:\\cvs/classistd/dlog/dlog.php,v 1.6 2003/04/29 19:28:57 darvin Exp $
	 *
	 * Copyright (C) 2003  Andrioli Darvin <darvina@libero.it>
	 *
	 *   This library is free software; you can redistribute it and/or
	 *   modify it under the terms of the GNU Lesser General Public
	 *   License as published by the Free Software Foundation; either
	 *   version 2 of the License, or (at your option) any later version.
	 *
	 *   This library is distributed in the hope that it will be useful,
	 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
	 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	 *   Lesser General Public License for more details.
	 *
	 *   You should have received a copy of the GNU Lesser General Public
	 *   License along with this library; if not, write to the Free Software
	 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
	 */
	 
	define('DLOG_USER_INFO',0);
	
	/**
	* class dlog
	*
	* 
	*
	*/
	class dlog {
		/**
		* I've opened the db? (TRUE/FALSE)
		*
		*/
		private $DBOpen = false;
		/**
		* Opened resource to database connection
		*
		* 
		*
		* @var $DbConn resource
		*/
		private $DbConn;
		/**
		* I've opened the flat file? (TRUE/FALSE)
		*
		* 
		*
		* @var $FlatOpen bool
		*/
		private $FlatOpen = false;
		/**
		* Opened flat file pointer
		*
		* 
		*
		* @var $FpFlat integer
		*/
		private $FpFlat;

		/**
		* Array with configuration settings per error level
		*
		* 
		*
		* @var $ErrorMgr array
		*/
		public $ErrorMgr;
		
		/**
		 * Db Parameters.
		 */
		public $DbSystem='YourDbServer';
		public $Dbname='';
		public $DbUser='';
		public $DbPassword='';
		public $LogTable='dlog';
		
		/**
		 * Mail parameters
		 */
		public $MailSubject='Error message';						// subject
		public $MailTo=array('dest1@corp.com','dest2@corp.com');	// Destination, may be an array of address
		public $MailSender='test@test.it';							// mail sender
		
		/**
		 * Flat file parameter
		 */
		public $FlatFileName='dlog.txt';							// your log file (if flat set to 1)
		
		
		/**
		* constructor
		*
		* 
		*
		*/
		public function __construct() {
			$this->DBOpen=FALSE;
			$this->FlatOpen=FALSE;

			/**
			 * dlog configuration file
			 * For each error, you may specify which action perform. 
			 * Default value 0 (Off)
			 */
			$this->ErrorMgr[DLOG_USER_INFO]=array(
												'display' => 1,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 0    // end the script
											);
			$this->ErrorMgr[E_USER_ERROR]=	array(
												'display' => 0,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 1    // end the script
											);
			$this->ErrorMgr[E_USER_WARNING]=array(
												'display' => 1,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 1    // end the script
											);
			$this->ErrorMgr[E_USER_NOTICE]=	array(
												'display' => 0,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 0    // end the script
											);			
			$this->ErrorMgr[E_WARNING]=		array(
												'display' => 0,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 0    // end the script
											);
			$this->ErrorMgr[E_NOTICE]=		array(
												'display' => 0,   // send the message to browser
												'mail'    => 0,   // send by e-mail
												'flat'    => 1,   // write out to flat file
												'db'      => 0,   // write to db
												'die'     => 0    // end the script
											);
		}
		
		/**
		* Set the function Log as new error handler
		*
		* 
		*
		* @return string Return the old error handler or FALSE on failure
		*/
		public function register_error_handler() {
			return(set_error_handler(array(&$this,'Log')));
		}
		
		/**
		* Write a new messagge via browser, log, mail, according to the configuration
		*
		* Parameter order as an PHP error handler
		*
		* @access public 
		* @parameter int $errno error number
		* @parameter char $errmsg error description
		* @parameter char $filename
		* @parameter int $linenum
		* @parameter char $vars
		* @return none 
		*/
		public function Log($errno, $errmsg, $filename, $linenum, $vars=0) {
			if(isset($this->ErrorMgr[$errno]['display'])) {
				$this->Log2Display($errno, $errmsg, $filename, $linenum);
			}
			if(isset($this->ErrorMgr[$errno]['mail'])) {
				$this->Log2Mail($errno, $errmsg, $filename, $linenum);
			}
			if(isset($this->ErrorMgr[$errno]['flat'])) {
				$this->Log2flat($errno, $errmsg, $filename, $linenum);
			}
			if(isset($this->ErrorMgr[$errno]['db'])) {
				$this->Log2db($errno, $errmsg, $filename, $linenum);
			}
			if(isset($this->ErrorMgr[$errno]['die']) && $this->ErrorMgr[$errno]['die']) {
				exit();
			}
		}
		
		/**
		* Write the message on the screen. Draw a simply msg box
		*
		* 
		*
		* @access private 
		* @parameter int errno error number
		* @parameter char errmsg error description
		* @parameter char filename
		* @parameter int linenum
		*/
		public function Log2Display($errno, $errmsg, $filename, $linenum) {
			if($this->ErrorMgr[$errno]['display']!=1) return;

			$ExtraP=$this->ExtraParam();
			$extra = '';
			while(list($key,$value)=each($ExtraP)) {
				$extra .= '<br />'.$key.': '.$value;
			}
			$ErrType = ($errno)?'Error':'Info';
			echo "
				<p>
					".$ErrType.": [".$errno."] - ".$errmsg."<br />
					File: ".$filename." at line".$linenum."<br />
					Rem.Addr: ".$_SERVER['REMOTE_ADDR']." Browser:".$_SERVER['HTTP_USER_AGENT'].
					$extra.
					"
				</p>
			";
		}
		
		/**
		* Send the error message by mail.
		*
		* Send the log by e-mail
		* Require the mail section in php.ini configured
		*
		* @access private 
		* @parameter int errno error number
		* @parameter char errmsg error description
		* @parameter char filename
		* @parameter int linenum
		*/
		public function Log2Mail($errno, $errmsg, $filename, $linenum) {
			if($this->ErrorMgr[$errno]['mail']!=1) return;
			
			$ErrType=($errno)?'Error':'Info';
			$Message=$ErrType.": [".$errno."] - ".$errmsg."\n File: ".$filename." at line".$linenum."\n"
					 ."Rem.Addr: ".$_SERVER['REMOTE_ADDR']." Browser:".$_SERVER['HTTP_USER_AGENT'];
			$ExtraP=$this->ExtraParam();
			while(list($key,$value)=each($ExtraP)) {
				$Message.= "\n".$key.': '.$value;
			}
			
			$Header="From: ".$this->MailSender." \r\n"
					."X-Mailer: PHP/" . phpversion();
		
			// for each destination send an e-mail
			foreach($this->MailTo as $mailTo) {
				mail($mailTo,$this->MailSubject,$Message,$Header);
			}
		}
		
		/**
		* Write out the error into a flat file.
		*
		* 
		*
		* @access private 
		* @parameter int errno error number
		* @parameter char errmsg error description
		* @parameter char filename
		* @parameter int linenum
		*/
		public function Log2Flat($errno, $errmsg, $filename, $linenum) {
			if($this->ErrorMgr[$errno]['flat']!=1) return;
			
			$this->OpenFlat();
			
			$ErrType=($errno)?'Error':'Info';
			$Message=date('r')." ".$ErrType.": [".$errno."] - ".$errmsg." File: ".$filename." at line".$linenum."
					 Rem.Addr: ".$_SERVER['REMOTE_ADDR']." Browser:".$_SERVER['HTTP_USER_AGENT'];
			
			$ExtraP=$this->ExtraParam();
			while(list($key,$value)=each($ExtraP)) {
				$Message.= " ".$key.': '.$value;
			}
			$Message.="\n";
			
			if(!fwrite($this->FpFlat,$Message)) {
			   die($this->InternalError('Error writing file:'.$this->FlatFileName.' Description:'.$php_errormsg,__FILE__,__LINE__));
			}
		}
		
		/**
		* Open the specified flat file
		*
		* 
		*
		* @access private 
		*/
		private function OpenFlat() {
			if(!$this->FlatOpen) {
				$this->FpFlat=@fopen($this->FlatFileName,'at')
					   or die( $this->InternalError( 'Error during open file: ' . $this->FlatFileName . ' Description: ' . $php_errormsg,__FILE__,__LINE__ ) );
				$this->FlatOpen=TRUE;
			}
		}
		
		/**
		* Write out the error into a db
		*
		* 
		*
		* @access private 
		* @parameter int errno error number
		* @parameter char errmsg error description
		* @parameter char filename
		* @parameter int linenum
		*/
		public function Log2Db($errno, $errmsg, $filename, $linenum) {
			if($this->ErrorMgr[$errno]['db']!=1) return;
			
			$Param=array(
						'DEvent' => date('YmdHis'),
						'Errno' => $errno,
						'Text' => $errmsg,
						'FileName' => $filename,
						'Line' => $linenum,
						'RemAddr' => $_SERVER['REMOTE_ADDR'],
						'Browser' => $_SERVER['HTTP_USER_AGENT']
						);
			$ExtraP=$this->ExtraParam();
			$field=array_merge($Param,$ExtraP);
			$this->WriteDb($field);
		}
		
		/**
		* Convert the array into sql string and execute it
		*
		* 
		*
		* @access private 
		* @parameter array field
		*/
		private function WriteDb($field) {
			$this->OpenDb();
			$sql='insert into ' . $this->LogTable.' ';
			$i=0;
			$comma=' ';
			$fieldName='';
			$value='';
			while (list ($key, $val) = each ($field)) {
				if($i) $comma=',';
				$fieldName.=$comma.$key;
				$value.=$comma.'\''.addslashes($val).'\'';
				$i++;
			}
			$sql.=' ('.$fieldName.') values ('.$value.')';
			$this->DbExec($sql);
		}
		
		/**
		* Handle the error risen inside the class
		*
		* 
		*
		* @access private 
		* @parameter char Message
		* @parameter char File source File
		* @parameter char Line line number
		*/
		private function InternalError($Message,$File,$Line) {
			 echo "<p>
				 Error: [internal] - ".$Message."<br />
				 File: ".$File." at line".$Line."
				</p>";
		}
		
		/**
		 * Add extra information to the standard message.
		 * You should extends this class and then insert
		 * your addtional informational information in the new one
		 *
		 * @access private
		 * @return array with the new parameters. The index should be:
		 *                array('ParamName' => 'ParamValue',...)
		 */
		private function ExtraParam() {
			// In the base class I don't define any extra parameter. 
			$Param=array();
			return($Param);
		}
		/**
		 * Group of function to perform database operations
		 */
		/**
		* Open the database connection
		*
		* Mysql version
		*
		* @access private 
		*/
		private function OpenDb() {
			if(!$this->DBOpen) {
				 $this->DbConn=mysql_connect($this->DbSystem,$this->DbUser,$this->DbPassword)
									 or die($this->InternalError('Error during connection to database server',__FILE__,__LINE__));
				 mysql_select_db($this->Dbname,$this->DbConn)
					  				or die($this->InternalError('Error during selection of database '.$this->Dbname,__FILE__,__LINE__));
				 $this->DBOpen=TRUE;
			}
		}
		
		/**
		* Execute a generic sql statement on the open conection
		*
		* Mysql version
		*
		* @access private 
		* @parameter char sql
		*/
		private function DbExec($sql) {
			 $this->OpenDb();
			 mysql_query($sql,$this->DbConn)
				  or die($this->InternalError('Sql error '.mysql_errno().','.mysql_error().' sql:' .$sql,__FILE__,__LINE__));
		}
	
	}	
?>